#include <head.h>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;

class HttpServer
{
public:
    HttpServer(const string & ip, unsigned short port)
    : _listenfd(createSocket())
    , _ip(ip)
    , _port(port)
    {}

    void start() {
        if(_listenfd < 0) {
            printf("HttpServer start failed!\n");
            return;
        }

        //设置监听套接字属性
        int on = 1;
        if(setsockopt(_listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
            perror("setsockopt");
            return;
        }

        if(setsockopt(_listenfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) {
            perror("setsockopt");
            return;
        }

        struct sockaddr_in serveraddr;
        bzero(&serveraddr, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_port = htons(_port);
        serveraddr.sin_addr.s_addr = inet_addr(_ip.c_str());

        if(bind(_listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) {
            perror("bind");
            return;
        }

        if(listen(_listenfd, 100) < 0) {
            perror("listen");
            return;
        }
    }

    void recvAndShow() {
        while(1) {
            int peerfd = accept(_listenfd, nullptr, nullptr);
            char buff[1024] = {0};
            int ret = read(peerfd, buff, sizeof(buff));
            cout << "ret:" << ret << " bytes." << endl;
            //cout << buff;
            printf("%s\n", buff);

            string respMsg = response();
            write(peerfd, respMsg.c_str(), respMsg.size());

            close(peerfd);
        }
    }

private:
    int createSocket()
    {
        int fd = socket(AF_INET, SOCK_STREAM, 0);
        if(fd < 0) {
            perror("sockekt");
        }
        return fd;
    }

    string response() 
    {
        //...构造一个响应报文
        string startLine = "HTTP/1.1 200 OK\r\n";
        string respBody = "hello, client";
        string headers = "Server: HttpServer\r\n";
        headers += "Content-Type: text/plain\r\n";
        headers += "Content-Length: " + std::to_string(respBody.size()); 
        headers += "\r\n";
        string emptyLine = "\r\n";
        return startLine + headers + emptyLine + respBody;
    }

private:
    int _listenfd;
    string _ip;
    unsigned short _port;
    
};

void test0()
{
    HttpServer httpServer("192.168.30.128", 1280);
    httpServer.start();
    httpServer.recvAndShow();
}


int main()
{
    test0();
    return 0;
};

